﻿using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Z2
{
    public partial class ExceptionReport : Form
    {

        private readonly Exception m_exception;
        private readonly string m_screenshotPath;
        private readonly BackgroundWorker m_reportWorker;

        public ExceptionReport(Exception exception)
        {
            this.InitializeComponent();
            this.m_exception = exception;
            this.tbName.Text = exception.GetType().FullName;
            this.tbDetail.Text = exception.ToString();

            try
            {
                ResolveTexture2D screenshot = Program.CurrentGame.GetScreenshot();
                this.m_screenshotPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".jpg");
                screenshot.Save(this.m_screenshotPath, ImageFileFormat.Jpg);
            }
            catch
            {
                this.m_screenshotPath = string.Empty;
            }

            this.m_reportWorker = new BackgroundWorker();
            this.m_reportWorker.WorkerSupportsCancellation = true;
            this.m_reportWorker.WorkerReportsProgress = false;
            this.m_reportWorker.DoWork += new DoWorkEventHandler(ReportWorker_DoWork);
            this.m_reportWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ReportWorker_RunWorkerCompleted);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if(this.m_reportWorker != null && this.m_reportWorker.IsBusy)
                this.m_reportWorker.CancelAsync();
            base.OnClosing(e);
        }

        private void btClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btReport_Click(object sender, EventArgs e)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(this.m_exception.GetType().FullName);
            builder.AppendLine("Message: " + this.m_exception.Message);
            builder.AppendLine("Stack trace: " + this.m_exception.StackTrace);

            if (this.m_exception.InnerException != null)
            {
                builder.AppendLine("Inner exceptions:");

                Exception inner = this.m_exception.InnerException;
                int number = 1;
                while (inner != null)
                {
                    builder.AppendLine("#" + number + ": " + inner.Message);
                    builder.AppendLine(inner.StackTrace);
                    inner = inner.InnerException;
                    ++number;
                }
            }

            if(Program.CurrentGame != null)
            {
                GraphicsDeviceManager graphics = Zelvici2.Graphics;
                builder.AppendLine();
                builder.AppendLine("Other informations");
                builder.AppendLine(string.Format("Resolution: {0}x{1}", graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight));
                // TODO
            }

            this.btReport.Enabled = false;
            this.m_reportWorker.RunWorkerAsync(builder.ToString());
        }

        private void ReportWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bool success = Convert.ToBoolean(e.Result) && e.Error == null;
            if(success)
            {
                btReport.Text = "Thank you";
                return;
            }
            btReport.Enabled = true;
            MessageBox.Show("Error while submiting report.\nPlease, try it again.", "Error", MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
        }

        private void ReportWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string data = Convert.ToString(e.Argument);
            string postData = "message=" + data;
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://report.knihovnik.net/");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = postData.Length;

            using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
            {
                writer.Write(postData);
            }
            string response = string.Empty;
            try
            {
                using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
                {
                    response = reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
            }
            
            response = response.Trim();
            e.Result = (string.Compare(response, "1", true) == 0);
        }

        public static void Show(Exception exception)
        {
            using (ExceptionReport report = new ExceptionReport(exception))
            {
                report.ShowDialog();
            }
        }
    }
}
